import { PromptTemplate } from '@/types/prompt';

export interface OptimizationSuggestion {
  id: string;
  type: 'length' | 'structure' | 'clarity' | 'keywords' | 'variables' | 'best-practice';
  severity: 'info' | 'warning' | 'error';
  title: string;
  description: string;
  suggestion: string;
  example?: string;
  impact: 'high' | 'medium' | 'low';
  autoFixAvailable: boolean;
}

export interface OptimizationReport {
  score: number;
  suggestions: OptimizationSuggestion[];
  strengths: string[];
  improvements: string[];
  bestPractices: BestPractice[];
}

export interface BestPractice {
  id: string;
  title: string;
  description: string;
  example: string;
  category: string;
}

/**
 * 提示词优化服务
 * 提供智能分析和优化建议
 */
class PromptOptimizerService {
  private bestPractices: BestPractice[] = [
    {
      id: 'bp1',
      title: '明确角色定位',
      description: '清晰定义AI的角色和专业领域',
      example: '你是一位专业的{domain}专家，拥有{years}年的实践经验',
      category: 'role'
    },
    {
      id: 'bp2',
      title: '使用具体指令',
      description: '避免模糊的描述，使用明确的动作词',
      example: '分析、总结、列出、比较、解释',
      category: 'instruction'
    },
    {
      id: 'bp3',
      title: '设定输出格式',
      description: '明确指定期望的输出格式和结构',
      example: '请以列表形式输出，每项包含标题和描述',
      category: 'format'
    },
    {
      id: 'bp4',
      title: '提供上下文',
      description: '给出必要的背景信息和限制条件',
      example: '在{context}的背景下，考虑{constraints}的限制',
      category: 'context'
    },
    {
      id: 'bp5',
      title: '使用示例',
      description: '通过示例说明期望的输出',
      example: '例如：输入X，输出Y',
      category: 'example'
    }
  ];

  private keywords = {
    positive: [
      '请', '详细', '专业', '清晰', '准确', '系统', '全面', '深入',
      '分析', '解释', '总结', '列出', '比较', '评估', '建议', '优化'
    ],
    negative: [
      '随便', '大概', '可能', '也许', '差不多', '随意', '简单说说'
    ],
    structure: [
      '首先', '其次', '然后', '最后', '步骤', '第一', '第二', '第三'
    ]
  };

  /**
   * 分析提示词并生成优化报告
   */
  analyzePrompt(prompt: string): OptimizationReport {
    const suggestions: OptimizationSuggestion[] = [];
    const strengths: string[] = [];
    const improvements: string[] = [];

    // 分析长度
    this.analyzeLength(prompt, suggestions, strengths, improvements);
    
    // 分析结构
    this.analyzeStructure(prompt, suggestions, strengths, improvements);
    
    // 分析清晰度
    this.analyzeClarity(prompt, suggestions, strengths, improvements);
    
    // 分析关键词
    this.analyzeKeywords(prompt, suggestions, strengths, improvements);
    
    // 分析变量使用
    this.analyzeVariables(prompt, suggestions, strengths, improvements);
    
    // 计算总分
    const score = this.calculateScore(prompt, suggestions);
    
    // 匹配最佳实践
    const relevantPractices = this.getRelevantBestPractices(prompt);

    return {
      score,
      suggestions,
      strengths,
      improvements,
      bestPractices: relevantPractices
    };
  }

  /**
   * 分析长度
   */
  private analyzeLength(
    prompt: string,
    suggestions: OptimizationSuggestion[],
    strengths: string[],
    improvements: string[]
  ) {
    const length = prompt.length;
    
    if (length < 50) {
      suggestions.push({
        id: 'length-too-short',
        type: 'length',
        severity: 'warning',
        title: '提示词过短',
        description: `当前长度${length}字符，建议至少50字符`,
        suggestion: '添加更多细节说明、角色定义或输出要求',
        impact: 'high',
        autoFixAvailable: false
      });
      improvements.push('增加提示词长度，提供更多细节');
    } else if (length > 1000) {
      suggestions.push({
        id: 'length-too-long',
        type: 'length',
        severity: 'warning',
        title: '提示词过长',
        description: `当前长度${length}字符，建议不超过1000字符`,
        suggestion: '精简冗余内容，保留核心指令',
        impact: 'medium',
        autoFixAvailable: false
      });
      improvements.push('精简提示词，去除冗余内容');
    } else {
      strengths.push('提示词长度适中');
    }
  }

  /**
   * 分析结构
   */
  private analyzeStructure(
    prompt: string,
    suggestions: OptimizationSuggestion[],
    strengths: string[],
    improvements: string[]
  ) {
    const lines = prompt.split('\n').filter(l => l.trim());
    const hasNumberedList = /^\d+\./m.test(prompt);
    const hasBulletList = /^[•\-\*]/m.test(prompt);
    const hasStructureWords = this.keywords.structure.some(kw => prompt.includes(kw));
    
    if (lines.length === 1 && prompt.length > 200) {
      suggestions.push({
        id: 'structure-no-breaks',
        type: 'structure',
        severity: 'info',
        title: '建议分段组织',
        description: '长文本建议分段以提高可读性',
        suggestion: '使用换行符分隔不同的指令部分',
        example: '角色定义\n\n任务说明\n\n输出要求',
        impact: 'medium',
        autoFixAvailable: true
      });
      improvements.push('改善文本结构，使用分段');
    }
    
    if (hasNumberedList || hasBulletList || hasStructureWords) {
      strengths.push('结构清晰，使用了列表或序号');
    }
  }

  /**
   * 分析清晰度
   */
  private analyzeClarity(
    prompt: string,
    suggestions: OptimizationSuggestion[],
    strengths: string[],
    improvements: string[]
  ) {
    const ambiguousWords = ['可能', '也许', '大概', '左右', '差不多', '随便'];
    const foundAmbiguous = ambiguousWords.filter(word => prompt.includes(word));
    
    if (foundAmbiguous.length > 0) {
      suggestions.push({
        id: 'clarity-ambiguous',
        type: 'clarity',
        severity: 'warning',
        title: '存在模糊表达',
        description: `发现模糊词汇：${foundAmbiguous.join('、')}`,
        suggestion: '使用更明确的表达，避免模糊词汇',
        impact: 'high',
        autoFixAvailable: true
      });
      improvements.push('消除模糊表达，使用明确词汇');
    } else {
      strengths.push('表达清晰明确');
    }
    
    // 检查是否有明确的指令动词
    const actionVerbs = ['分析', '解释', '总结', '列出', '比较', '生成', '创建', '编写'];
    const hasActionVerbs = actionVerbs.some(verb => prompt.includes(verb));
    
    if (!hasActionVerbs && prompt.length > 50) {
      suggestions.push({
        id: 'clarity-no-action',
        type: 'clarity',
        severity: 'info',
        title: '缺少明确指令',
        description: '未发现明确的动作指令',
        suggestion: `添加明确的动作词，如：${actionVerbs.slice(0, 3).join('、')}等`,
        impact: 'medium',
        autoFixAvailable: false
      });
    }
  }

  /**
   * 分析关键词
   */
  private analyzeKeywords(
    prompt: string,
    suggestions: OptimizationSuggestion[],
    strengths: string[],
    improvements: string[]
  ) {
    const positiveCount = this.keywords.positive.filter(kw => prompt.includes(kw)).length;
    const negativeCount = this.keywords.negative.filter(kw => prompt.includes(kw)).length;
    
    if (negativeCount > 0) {
      suggestions.push({
        id: 'keywords-negative',
        type: 'keywords',
        severity: 'warning',
        title: '包含消极词汇',
        description: '消极词汇可能导致输出质量下降',
        suggestion: '替换为更积极、专业的表达',
        impact: 'medium',
        autoFixAvailable: true
      });
      improvements.push('替换消极词汇');
    }
    
    if (positiveCount >= 3) {
      strengths.push('使用了丰富的积极词汇');
    } else if (positiveCount === 0) {
      suggestions.push({
        id: 'keywords-no-positive',
        type: 'keywords',
        severity: 'info',
        title: '缺少强化词汇',
        description: '添加积极词汇可以提升输出质量',
        suggestion: `考虑添加：${this.keywords.positive.slice(0, 3).join('、')}等词汇`,
        impact: 'low',
        autoFixAvailable: false
      });
    }
  }

  /**
   * 分析变量使用
   */
  private analyzeVariables(
    prompt: string,
    suggestions: OptimizationSuggestion[],
    strengths: string[],
    improvements: string[]
  ) {
    const variablePattern = /\{([^}]+)\}/g;
    const variables = prompt.match(variablePattern) || [];
    
    if (variables.length > 0) {
      strengths.push(`使用了${variables.length}个变量，提高了灵活性`);
      
      // 检查变量命名
      const poorNames = variables.filter(v => {
        const name = v.slice(1, -1);
        return name.length === 1 || /^\d/.test(name);
      });
      
      if (poorNames.length > 0) {
        suggestions.push({
          id: 'variables-poor-naming',
          type: 'variables',
          severity: 'info',
          title: '变量命名可优化',
          description: `变量${poorNames.join('、')}命名不够清晰`,
          suggestion: '使用描述性的变量名，如{userName}、{topicName}',
          impact: 'low',
          autoFixAvailable: false
        });
      }
    } else if (prompt.length > 200) {
      suggestions.push({
        id: 'variables-not-used',
        type: 'variables',
        severity: 'info',
        title: '可考虑使用变量',
        description: '使用变量可以提高提示词的复用性',
        suggestion: '将可变内容提取为变量，如{topic}、{style}',
        example: '将"人工智能"替换为{topic}变量',
        impact: 'medium',
        autoFixAvailable: false
      });
      improvements.push('考虑添加变量以提高灵活性');
    }
  }

  /**
   * 计算总分
   */
  private calculateScore(prompt: string, suggestions: OptimizationSuggestion[]): number {
    let score = 100;
    
    // 根据建议扣分
    suggestions.forEach(suggestion => {
      if (suggestion.severity === 'error') {
        score -= 20;
      } else if (suggestion.severity === 'warning') {
        score -= 10;
      } else {
        score -= 5;
      }
    });
    
    // 长度加分
    const length = prompt.length;
    if (length >= 100 && length <= 500) {
      score += 5;
    }
    
    // 结构加分
    if (prompt.includes('\n')) {
      score += 5;
    }
    
    // 确保分数在0-100之间
    return Math.max(0, Math.min(100, score));
  }

  /**
   * 获取相关的最佳实践
   */
  private getRelevantBestPractices(prompt: string): BestPractice[] {
    const relevant: BestPractice[] = [];
    
    // 根据提示词内容推荐相关实践
    if (!prompt.includes('你是') && !prompt.includes('作为')) {
      relevant.push(this.bestPractices[0]); // 角色定位
    }
    
    if (prompt.length < 100) {
      relevant.push(this.bestPractices[1]); // 具体指令
    }
    
    if (!prompt.includes('格式') && !prompt.includes('输出')) {
      relevant.push(this.bestPractices[2]); // 输出格式
    }
    
    return relevant.slice(0, 3); // 最多返回3个建议
  }

  /**
   * 自动修复提示词
   */
  async autoFix(prompt: string, suggestionIds: string[]): Promise<string> {
    let fixed = prompt;
    
    // 根据建议ID应用修复
    if (suggestionIds.includes('structure-no-breaks')) {
      // 自动添加分段
      fixed = this.addLineBreaks(fixed);
    }
    
    if (suggestionIds.includes('clarity-ambiguous')) {
      // 替换模糊词汇
      fixed = this.replaceAmbiguousWords(fixed);
    }
    
    if (suggestionIds.includes('keywords-negative')) {
      // 替换消极词汇
      fixed = this.replaceNegativeWords(fixed);
    }
    
    return fixed;
  }

  /**
   * 添加换行符
   */
  private addLineBreaks(prompt: string): string {
    // 简单的分段逻辑
    const sentences = prompt.match(/[^。！？.!?]+[。！？.!?]/g) || [];
    if (sentences.length > 3) {
      const midPoint = Math.floor(sentences.length / 2);
      return sentences.slice(0, midPoint).join('') + '\n\n' + sentences.slice(midPoint).join('');
    }
    return prompt;
  }

  /**
   * 替换模糊词汇
   */
  private replaceAmbiguousWords(prompt: string): string {
    const replacements: Record<string, string> = {
      '可能': '将',
      '也许': '将',
      '大概': '约',
      '左右': '约',
      '差不多': '接近',
      '随便': '任意'
    };
    
    let fixed = prompt;
    Object.entries(replacements).forEach(([from, to]) => {
      fixed = fixed.replace(new RegExp(from, 'g'), to);
    });
    
    return fixed;
  }

  /**
   * 替换消极词汇
   */
  private replaceNegativeWords(prompt: string): string {
    const replacements: Record<string, string> = {
      '随便': '请',
      '简单说说': '详细说明',
      '差不多就行': '准确完成'
    };
    
    let fixed = prompt;
    Object.entries(replacements).forEach(([from, to]) => {
      fixed = fixed.replace(new RegExp(from, 'g'), to);
    });
    
    return fixed;
  }

  /**
   * 获取优化建议的优先级
   */
  getSuggestionPriority(suggestion: OptimizationSuggestion): number {
    const severityScore = {
      error: 3,
      warning: 2,
      info: 1
    };
    
    const impactScore = {
      high: 3,
      medium: 2,
      low: 1
    };
    
    return severityScore[suggestion.severity] * 10 + impactScore[suggestion.impact];
  }

  /**
   * 比较两个提示词
   */
  comparePrompts(promptA: string, promptB: string): {
    better: 'A' | 'B' | 'equal';
    comparison: {
      aspect: string;
      scoreA: number;
      scoreB: number;
    }[];
  } {
    const reportA = this.analyzePrompt(promptA);
    const reportB = this.analyzePrompt(promptB);
    
    const comparison = [
      {
        aspect: '总体得分',
        scoreA: reportA.score,
        scoreB: reportB.score
      },
      {
        aspect: '建议数量',
        scoreA: 100 - reportA.suggestions.length * 10,
        scoreB: 100 - reportB.suggestions.length * 10
      },
      {
        aspect: '优势数量',
        scoreA: reportA.strengths.length * 20,
        scoreB: reportB.strengths.length * 20
      }
    ];
    
    const totalA = comparison.reduce((sum, c) => sum + c.scoreA, 0);
    const totalB = comparison.reduce((sum, c) => sum + c.scoreB, 0);
    
    return {
      better: totalA > totalB ? 'A' : totalB > totalA ? 'B' : 'equal',
      comparison
    };
  }
}

// 导出单例实例
export const promptOptimizer = new PromptOptimizerService();

// 导出类用于测试
export { PromptOptimizerService };